home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 20 / Cream of the Crop 20 (Terry Blount) (1996).iso / math / alged34.zip / ALGEDSRC.ZIP / ALGRAPH.C < prev    next >
C/C++ Source or Header  |  1996-06-06  |  26KB  |  839 lines

  1. /*--------------------------------------------------------------------
  2.    Alged:  Algebra Editor    henckel@vnet.ibm.com
  3.  
  4.    Copyright (c) 1994 John Henckel
  5.    Permission to use, copy, modify, distribute and sell this software
  6.    and its documentation for any purpose is hereby granted without fee,
  7.    provided that the above copyright notice appear in all copies.
  8. */
  9. #include "alged.h"
  10. #include <graphics.h>
  11. #include <dos.h>
  12. /*
  13.   xs is size
  14.   xo is origin (left edge)
  15.   xz is maxx/xs (number of pixels per unit length)
  16.   np is number of points
  17. */
  18. static node* defx;     // default fx
  19. static double xs=0,xo,ys,yo,xz,yz,np,ts,to;
  20. static double err,step;
  21. static node ivar[10];       /* independent variables */
  22. static int gm,polar,nv,rain,fill;
  23. static int co1,co2,co3;    /* colors */
  24. extern char gdriver[80];
  25. extern int gmode,psz,pst;
  26. /*-----------------------------------------------------------------
  27.   Palette variables
  28. */
  29. typedef struct { unsigned char r,g,b; } palen;
  30. static palen pal[480];
  31. static int v256;
  32. /*-----------------------------------------------------------------
  33.   3d variables
  34. */
  35. static int in3d,vix=1;
  36. static double focalen = 5, cont;
  37. static double cx,cy,cz;    // camera location
  38. static double ax,ay,az;    // camera orientation
  39. static double m[4][4];     // transform matrix
  40. extern double lightx,lighty,lightz;  // see algfile.c
  41. #define EPS 1E-200
  42. /* These are the zooming ratios.... rr1 is (1-rr)/2 */
  43. #define rr 0.7
  44. #define rr1 0.15
  45. #define tt (M_PI/72)
  46.  
  47. typedef struct {       // save previous row data for polyfill
  48.   short x2,y2;          // screen location
  49. } point2d;
  50.  
  51. typedef struct {       // save previous row data for polyfill
  52.   double x,y,z;         // 3d location
  53. } point3d;
  54.  
  55. /*-----------------------------------------------------------------
  56.    find var
  57. */
  58. double getvar(char *name) { int i;
  59.   for (i=0; i<nv; ++i)
  60.     if (!strcmp(name,ivar[i].name)) return ivar[i].value;
  61.   return 0.0;
  62. }
  63.  
  64. /*-----------------------------------------------------------------
  65.   min and max
  66.   */
  67. double mind(double x, double y) {
  68.   return min(x,y);
  69. }
  70. double maxd(double x, double y) {
  71.   return max(x,y);
  72. }
  73.  
  74. /*-----------------------------------------------------------------
  75.    gray_palette
  76. */
  77. void gray_palette()
  78. {
  79.   int i;
  80.   for (i=0; i<120; ++i)   pal[i].r = pal[i].g = pal[i].b = i/2+3;
  81.   for (i=120; i<240; ++i) pal[i].r = pal[i].g = pal[i].b = 123-i/2;
  82.   for (i=0; i<240; ++i)   pal[i+240] = pal[i];
  83. }
  84.  
  85. /*-----------------------------------------------------------------
  86.    wave_palette
  87. */
  88. #define cwav(r) 31*(sin((i+r)*M_PI/120)+1)
  89. // #define cwav(r) max(min(abs((i+r)%240-120)-40,40),0)*63/40
  90. void wave_palette()
  91. {
  92.   int i;
  93.   for (i=0; i<240; ++i) {
  94.     pal[i].r = cwav(0);
  95.     pal[i].g = cwav(80);
  96.     pal[i].b = cwav(160);
  97.   }
  98.   for (i=0; i<240; ++i)   pal[i+240] = pal[i];
  99. }
  100.  
  101. /*  positive modulo  */
  102. long pmod(long x,long y) {
  103.   if (y==0) return x;
  104.   if (y<0) y=-y;
  105.   x = x % y;
  106.   if (x < 0) x += y;
  107.   return x;
  108. }
  109.  
  110. /*-----------------------------------------------------------------
  111.    set_palette - set the top 240 colors of the vga palette
  112. */
  113. void set_palette(int i)
  114. {
  115.  struct REGPACK r;
  116.  i = pmod(i,240);
  117.  r.r_ax = 0x1012;
  118.  r.r_bx = 0x0010;     /* start */
  119.  r.r_cx = 0x00F0;     /* length */
  120.  r.r_es = FP_SEG(pal);
  121.  r.r_dx = FP_OFF(pal) + i*sizeof*pal;
  122.  intr(0x10, &r);
  123. }
  124.  
  125. /*-----------------------------------------------------------------
  126.    eval - return value of p, using ivar
  127. */
  128. double eval(node *p) {
  129.   double u,v;
  130.   if (!p) return 0;
  131.   switch (p->kind) {
  132.   case VAR: return getvar(p->name);
  133.   case NUM: return p->value;
  134.   case ADD: return eval(p->lf) + eval(p->rt);
  135.   case SUB: return eval(p->lf) - eval(p->rt);
  136.   case MUL: return eval(p->lf) * eval(p->rt);
  137.   case DIV:
  138.     v = eval(p->rt);
  139.     if (fabs(v)<err) return 0;
  140.     return eval(p->lf) / v;
  141.   case EXP:
  142.     u = eval(p->lf);
  143.     v = eval(p->rt);
  144.     if (u<err && !whole(v)) modf(v,&v);    // result would be imaginary
  145.     if (fabs(v * log10(fabs(u)+1)) > 300) return 0;
  146.     if (!v) return 0;
  147.     return pow(u,v);
  148.   case EQU: return mind(eval(p->lf),eval(p->rt));
  149.   case FUN:
  150.     if (!strcmp(p->name,"sin")) return sin(eval(p->lf));
  151.     if (!strcmp(p->name,"cos")) return cos(eval(p->lf));
  152.     if (!strcmp(p->name,"tan")) return tan(eval(p->lf));
  153.     if (!strcmp(p->name,"asin")) {
  154.       v = eval(p->lf);
  155.       if (v>1 || v<-1) return 0;
  156.       return asin(v);
  157.     }
  158.     if (!strcmp(p->name,"acos")) {
  159.       v = eval(p->lf);
  160.       if (v>1 || v<-1) return 0;
  161.       return acos(v);
  162.     }
  163.     if (!strcmp(p->name,"atan")) return atan(eval(p->lf));
  164.     if (!strcmp(p->name,"sinh")) return sinh(eval(p->lf));
  165.     if (!strcmp(p->name,"cosh")) return cosh(eval(p->lf));
  166.     if (!strcmp(p->name,"tanh")) return tanh(eval(p->lf));
  167.     if (!strcmp(p->name,"rand")) return eval(p->lf)*rand()/RAND_MAX;
  168.     if (!strcmp(p->name,"sign")) {
  169.       v = eval(p->lf);
  170.       return v<0?-1:v>0?1:0;
  171.     }
  172.     if (!strcmp(p->name,"ln")) {
  173.       v = eval(p->lf);
  174.       if (v<=0) return 0;
  175.       return log(v);
  176.     }
  177.     if (!strcmp(p->name,"log")) {
  178.       v = eval(p->lf);
  179.       if (v<=0) return 0;
  180.       return log10(v);
  181.     }
  182.     if (!strcmp(p->name,"abs")) return fabs(eval(p->lf));
  183.     if (!strcmp(p->name,"r") && p->nump==2) return hypot(eval(p->lf),eval(p->rt));
  184.     if (!strcmp(p->name,"min") && p->nump==2) return mind(eval(p->lf),eval(p->rt));
  185.     if (!strcmp(p->name,"max") && p->nump==2) return maxd(eval(p->lf),eval(p->rt));
  186.     if (!strcmp(p->name,"atan2") && p->nump==2) {
  187.       u = eval(p->lf);
  188.       v = eval(p->rt);
  189.       if (v==0 && u==0) return 0;
  190.       return atan2(u,v);
  191.     }
  192.     if (!strcmp(p->name,"mod") && p->nump==2) return fmod(eval(p->lf),eval(p->rt));
  193.   default: return 0;
  194.   }
  195. }
  196.  
  197. /*-----------------------------------------------------------------
  198.    reset window,  use a weird number for xs to get better safety
  199. */
  200. void resetx() { int i;
  201.   xs = 7-M_PI/13; ys = xs*0.75;
  202.   xo=xs/-2; yo=ys/-2; np=25;
  203.   err = pow(10,-sigdig);  step=1.0;
  204.   for (i=0; i<10; ++i) ivar[i].value = 0;
  205.   cz=2.5; cy=2.58819; cx=9.33013;   // camera location
  206.   ax=.261799; ay=M_PI/2+ax; az=0;   // camera orientation
  207.   ts=xs; to=xo;      vix=1;
  208.   co1=15; co2=2; co3=1; rain=0;
  209.   focalen=5; fill=0; polar=0; cont=0.2;
  210. }
  211. /*-----------------------------------------------------------------
  212.    add a new var
  213. */
  214. void addvar(char *name) { int i;
  215.   for (i=0; i<nv; ++i) if (!strcmp(name,ivar[i].name)) break;
  216.   if (i==nv && nv<10) strcpy(ivar[nv++].name,name);
  217. }
  218. /*-----------------------------------------------------------------
  219.    look for the first var in p
  220. */
  221. void setivar(node *p) { int i;
  222.   if (p->kind==VAR) addvar(p->name);
  223.   for (i=0; i<p->nump; ++i) setivar(p->parm[i]);
  224. }
  225.  
  226. /*-----------------------------------------------------------------
  227.    show help file
  228. */
  229. void showghelp() {
  230.   FILE *f;
  231.   int i,c=0;
  232.   static char s[85];
  233.  
  234.   strcpy(s,"alged");
  235.   strcat(s,lang);
  236.   strcat(s,".hlq");
  237.   f = fopen(s,"r");
  238.   if (!f) { printf(msg[16],s);
  239.     pause; return;
  240.   }
  241.   restorecrtmode();
  242.   if (ti.screenheight>25) textmode(64);    /* ega 43 line mode */
  243.   textattr(norm);
  244.   clrscr();
  245.   i = ti.screenheight-1;
  246.   while (!feof(f)) {
  247.     printf(fgets(s,80,f));
  248.     if (!--i) {
  249.       i = ti.screenheight-4;
  250.       while (!(c=getch()));
  251.       if (c==27) break;
  252.     }
  253.   }
  254.   if (c!=27) getch();
  255.   fclose(f);
  256.   setgraphmode(gmode);
  257. }
  258. /*-----------------------------------------------------------------
  259.    rotate vars     starting at index i
  260. */
  261. void rot_var(int i) {
  262.   node t;
  263.   if (nv < 2) return;
  264.   t = ivar[i];
  265.   t.value = 0;
  266.   for (++i; i<nv; ++i) {
  267.     ivar[i-1] = ivar[i];
  268.     ivar[i-1].value = 0;
  269.   }
  270.   ivar[nv-1] = t;
  271.   strcpy(defx->name,ivar[0].name);    // default fx is ivar[0]
  272. }
  273. /*-----------------------------------------------------------------
  274.    handle key
  275. */
  276. void handlekey(char c) {
  277.   switch (c) {
  278.     case ';': showghelp(); break;     /* F1 */
  279.     case 72: yo+=ys/4; break;
  280.     case 75: xo-=xs/4; break;
  281.     case 77: xo+=xs/4; break;